﻿using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;

namespace Oxage.CNC.Models
{
	public class GCodeInline : IMachineCodeInline
	{
		#region Constructors
		public GCodeInline()
		{
		}

		public GCodeInline(string inline)
		{
			Parse(inline);
		}
		#endregion

		#region Public properties
		public char Code
		{
			get;
			set;
		}

		public double? Value
		{
			get;
			set;
		}

		public string Comment
		{
			get;
			set;
		}

		public bool IsMultilineComment
		{
			get;
			set;
		}
		#endregion

		#region Public methods
		public void Parse(string inline)
		{
			var match = Regex.Match(inline, @"(?<code>\w)(?<value>[\d\-\+\.]+)", RegexOptions.IgnoreCase);
			if (match.Success)
			{
				this.Code = match.Groups["code"].Value[0];
				this.Value = double.Parse(match.Groups["value"].Value, CultureInfo.InvariantCulture);
				this.Comment = null;
			}
			else if (inline.StartsWith(";"))
			{
				this.Comment = inline.Substring(1);
				this.IsMultilineComment = false;
			}
			else if (Regex.IsMatch(inline, @"^\s*[\(\{].*[\)\}]\s*$"))
			{
				inline = inline.Trim();
				this.Comment = inline.Remove(inline.Length - 1).Substring(1);
				this.IsMultilineComment = true;
			}
		}

		public override string ToString()
		{
			if (!string.IsNullOrEmpty(this.Comment))
			{
				//Inline is a comment
				return this.IsMultilineComment ? "(" + this.Comment + ")" : ";" + this.Comment;
			}
			else
			{
				//Inline is a code and value
				string value = (this.Value != null ? this.Value.Value.ToString(CultureInfo.InvariantCulture) : null);
				return string.Format("{0}{1}", this.Code, value).ToUpper();
			}
		}
		#endregion

		#region IMachineCodeInline Members
		public byte[] ToBytes()
		{
			return Encoding.ASCII.GetBytes(ToString());
		}

		public void FromBytes(byte[] data)
		{
			Parse(Encoding.ASCII.GetString(data));
		}
		#endregion
	}
}
